package com.atguigu.gmall.payment.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentService;
import jdk.nashorn.internal.ir.annotations.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/api/payment/alipay")
@RefreshScope
public class AlipayController {

    @Autowired
    AlipayService alipayService;

    @Autowired
    PaymentService paymentService;

    @Autowired
    RedisTemplate redisTemplate;

    @Value("${app_id}")
    private String app_id;

    @RequestMapping("submit/{orderId}")
    @ResponseBody
    public String submitOrder(@PathVariable Long orderId){
        return alipayService.createaliPay(orderId);
    }

    /**
     * 支付宝回调
     * @return
     */
    @GetMapping("callback/return")
    public String callBack() {
        // 同步回调给用户展示信息
        return "redirect:" + AlipayConfig.return_order_url;
    }

    @PostMapping("/callback/notify")
    public String callbackNotify(@RequestParam Map<String,String> paramMap ){
        System.out.println("你回来了啊");

        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(paramMap, AlipayConfig.alipay_public_key, AlipayConfig.charset,AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        //  获取异步通知的参数中的订单号！
        String outTradeNo = paramMap.get("out_trade_no");
        //  获取异步通知的参数中的订单总金额！
        String totalAmount = paramMap.get("total_amount");
        //  获取异步通知的参数中的appId！
        String appId = paramMap.get("app_id");
        //  获取异步通知的参数中的交易状态！
        String tradeStatus = paramMap.get("trade_status");
        //  保证异步通知的幂等性！notify_id
        String notifyId = paramMap.get("notify_id");

        if(signVerified){
            //  根据outTradeNo 查询数据！
            PaymentInfo paymentInfo = this.paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());

            if(paymentInfo==null || new BigDecimal("0.01").compareTo(new BigDecimal(totalAmount))!=0 || !appId.equals(app_id)) {
                return "failure";
            }


            Boolean result = this.redisTemplate.opsForValue().setIfAbsent(notifyId, notifyId, 1462, TimeUnit.MINUTES);
            if(!result){
                return "failure";
            }
            if("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){
                //  修改交易记录状态！再订单状态！
                this.paymentService.paySucess(outTradeNo,PaymentType.ALIPAY.name(),paramMap);
                return "success";
            }else {
                // TODO 验签失败则记录异常日志，并在response中返回failure.
                return "failure";
            }
        }
        return "";
    }
    //发起退款
    @RequestMapping("refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable Long orderId){
        boolean flag = alipayService.refund(orderId);

        return Result.ok(flag);
    }
    // 根据订单Id关闭订单
    @GetMapping("closePay/{orderId}")
    @ResponseBody
    public Boolean closePay(@PathVariable Long orderId){
        Boolean flag = alipayService.closePay(orderId);
        return flag;
    }
    // 查看是否有交易记录
    @RequestMapping("checkPayment/{orderId}")
    @ResponseBody
    public Boolean checkPayment(@PathVariable Long orderId){
        Boolean flag = alipayService.checkPayment(orderId);
        return flag;
    }
    //查询PaymentInfo 数据接口
    @GetMapping("getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo){
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        if (null!=paymentInfo){
            return paymentInfo;
        }
        return null;
    }
}
